package lapsnake.model.expr;

import gui.typeEditors.DoubleEditor;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;

import lapsnake.model.*;
import lapsnake.model.data.*;
import lapsnake.model.dnd.ActionNodePanel;
import lapsnake.py.ast.Value;
import lapsnake.ui.Fonts;

import org.python.antlr.ast.*;
import org.python.core.*;

/**Wrapper class with helper functions for Num nodes*/
public class LapNum extends LapExpression implements Value<Number>, VetoableChangeListener {
	public final VetoableProperty<Number> value = new VetoableProperty<>(this, Number.class);
	
	public LapNum(PyAST pyAST, ChildField<? super LapNum> parent, Num node) throws PropertyVetoException {
		super(pyAST, parent, node);
		Object pNumber = node.getInternalN();
		Number jNumber;
		if(pNumber instanceof Number)
			jNumber = (Number)pNumber;
		else if(pNumber instanceof PyInteger)
			jNumber = ((PyInteger)pNumber).getValue();
		else if(pNumber instanceof PyFloat)
			jNumber = ((PyFloat)pNumber).getValue();
		else if(pNumber instanceof PyLong)
			jNumber = ((PyLong)pNumber).getValue().longValue();//Cheating
		else if(pNumber instanceof PyBoolean)
			jNumber = ((PyBoolean)pNumber).getValue();
		else
			throw new IllegalArgumentException(node+" is not a number!");
		value.setInternal(jNumber);
		buildTextNodes(node);
	}
	@Override
	public Number value()
	{
		return value.get();
	}
	
	@Override
	protected void populateCompactUI(ActionNodePanel<LapNode> ui)
	{
		//TODO broader number support, not really any need to parse as java number?
		DoubleEditor editor = new DoubleEditor(value.get().doubleValue(), 1);
		editor.setFont(Fonts.smallUI);
		editor.setForeground(new Color(0x721229));
		editor.addActionListener(new ActionListener()
		{
			//Note: need lis reference to live as long as the editor does, or the weakreference might be destroyed prematurely
			TypedListener<Number> lis;
			{
				lis = new TypedListener<Number>(){
					@Override
					public void valueChanged(
						Property<? extends Number> property, Number oldValue)
					{
						//Update editor to reflect new value
						editor.setValue(property.get().doubleValue());
					}
					
				};
				value.addListener(lis);
			}
			@Override
			public void actionPerformed(ActionEvent e)
			{
				try
				{
					//Update value from editor
					//Exclude lis to prevent unnecessary reacharound.
					value.change(editor.getValue(), lis, true);
				}
				catch (PropertyVetoException err)
				{
					//Reset value if it failed
					ui.rootPanel.userError(editor, err);
					editor.setValue(value.get().doubleValue());
				}
			}
		});
		ui.add(editor);
	}
	
	@Override
	public void vetoableChange(PropertyChangeEvent evt)
		throws PropertyVetoException
	{
		// TODO Auto-generated method stub
	}
}
